<template>
  <div v-if="selectionConfig.show" ref="dom" class="selection" :style="style">
  </div>
</template>

<script setup lang="ts">
  import {
    CSSProperties,
    computed,
    nextTick,
    onMounted,
    onUnmounted,
    ref,
  } from 'vue';
  import { intersect } from '@/utils/utils';
  import { selectionConfig } from './bus';
  import { selectedKey } from '../data/bus';

  const dom = ref();
  const clear = () => {
    selectionConfig.value.show = false;
    document.onmouseup = null;
    document.onmousemove = null;
    selectionConfig.value.width = 0;
    selectionConfig.value.height = 0;
  };
  onMounted(() => {
    document.onmousedown = (event) => {
      const startX = event.pageX;
      const startY = event.pageY;
      const targetDom = event.target as HTMLElement;
      if (!targetDom.hasAttribute('data-selection-area')) {
        return;
      }
      selectedKey.value.clear();
      document.onmousemove = (e: MouseEvent) => {
        const width = e.pageX - startX;
        const height = e.pageY - startY;
        const targets = document.querySelectorAll('[data-selection]');
        nextTick(() => {
          const domEl = dom.value as HTMLDivElement;

          if (!domEl) return;
          const r2 = domEl.getBoundingClientRect();
          Array.from(targets).forEach((element) => {
            const r1 = element.getBoundingClientRect();
            const targetId = element.getAttribute('data-selection') || '';
            if (intersect(r1, r2)) {
              selectedKey.value.add(targetId);
            } else {
              selectedKey.value.delete(targetId);
            }
          });
        });
        selectionConfig.value.left = width < 0 ? startX + width : startX;
        selectionConfig.value.top = height < 0 ? startY + height : startY;
        selectionConfig.value.width = Math.abs(width);
        selectionConfig.value.height = Math.abs(height);
        selectionConfig.value.show = true;
      };
      document.onmouseup = () => {
        document.onmousemove = null;
        selectionConfig.value.show = false;
      };
    };
  });

  onUnmounted(() => {
    clear();
  });
  const style = computed((): CSSProperties => {
    return {
      left: `${selectionConfig.value.left}px`,
      top: `${selectionConfig.value.top}px`,
      width: `${selectionConfig.value.width}px`,
      height: `${selectionConfig.value.height}px`,
    };
  });
</script>

<style lang="scss" scoped>
  .selection {
    position: fixed;
    background-color: #81b3f565;
    border: 1px solid var(--blue);
  }
</style>
